package java学习.leetcode.editor.cn.链表;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 刘世锦
 * 2022-09-29 14:36:10	 当前时间
 */
//设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性：val 和 next。val 是当前节点的值，next 是指向下一个节点的指针
///引用。如果要使用双向链表，则还需要一个属性 prev 以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。 
//
// 在链表类中实现这些功能： 
//
// 
// get(index)：获取链表中第 index 个节点的值。如果索引无效，则返回-1。 
// addAtHead(val)：在链表的第一个元素之前添加一个值为 val 的节点。插入后，新节点将成为链表的第一个节点。 
// addAtTail(val)：将值为 val 的节点追加到链表的最后一个元素。 
// addAtIndex(index,val)：在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度，则该节点将附加
//到链表的末尾。如果 index 大于链表长度，则不会插入节点。如果index小于0，则在头部插入节点。 
// deleteAtIndex(index)：如果索引 index 有效，则删除链表中的第 index 个节点。 
// 
// 示例：
//MyLinkedList linkedList = new MyLinkedList();
//linkedList.addAtHead(1);
//linkedList.addAtTail(3);               0   1   2
//linkedList.addAtIndex(1,2);   //链表变为1-> 2-> 3
//linkedList.get(1);            //返回2
//linkedList.deleteAtIndex(1);  //现在链表是1-> 3
//linkedList.get(1);            //返回3
//
// 提示： 
//
// 
// 0 <= index, val <= 1000 
// 请不要使用内置的 LinkedList 库。 
// get, addAtHead, addAtTail, addAtIndex 和 deleteAtIndex 的操作次数不超过 2000。 
// 
// Related Topics 设计 链表 
// 👍 637 👎 0

public class 设计链表_Mine {
	public static void main(String[] args) {
        MyLinkedList solution = new 设计链表_Mine().new MyLinkedList();
        MyLinkedList linkedList = solution ;
//        linkedList.addAtHead(1);
//        linkedList.addAtTail(3);
//        linkedList.addAtIndex(1,2);   //链表变为1-> 2-> 3
//        System.out.println(linkedList.get(1));      //返回2
//        linkedList.deleteAtIndex(1);  //现在链表是1-> 3
//        System.out.println(linkedList.get(1));           //返回3

//        测试用例:["MyLinkedList","addAtHead","deleteAtIndex"]
//			[[],[1],[0]]
        linkedList.addAtHead(1);
        linkedList.addAtTail(3);
        linkedList.addAtIndex(3,2);   //链表变为1-> 2-> 3
//        System.out.println(linkedList.get(1));      //返回2
//        linkedList.deleteAtIndex(0);
//        linkedList.//print();
//        System.out.println(linkedList.get(0));
//        System.out.println(linkedList.get(1));      //返回2


//        linkedList.addAtIndex(0,10);
//        linkedList.addAtIndex(0,20);
//        linkedList.addAtIndex(1,30);
        System.out.println(linkedList.get(0));

    }
//leetcode submit region begin(Prohibit modification and deletion)
class MyLinkedList {
	    int size;
	    ListNode head;
    public MyLinkedList() {

    }
//linkedList.addAtHead(1);
//linkedList.addAtTail(3);               0   1   2
//linkedList.addAtIndex(1,2);   //链表变为1-> 2-> 3
//linkedList.get(1);            //返回2
//linkedList.deleteAtIndex(1);  //现在链表是1-> 3
//linkedList.get(1);            //返回3
    public int get(int index) {
        if (index<0||index>=getSize()){
            return -1;
        }
        ListNode node = head;
        //  0 1 2
        //  1 3 3
//        if (index==0){
//            return head.val;
//        }
        for (int j = 0; j <index; j++) {
                node = node.next;
        }

        return node.val;
    }
    public int getSize(){
        ListNode node = head;
        int count =0;
        while (node!=null){
            node = node.next;
            size++;
            count++;
        }
        return count;
    }
    
    public void addAtHead(int val) {
        ListNode node = new ListNode(val);
        node.next = head;
        head = node;
        getSize(); //print();
    }
    
    public void addAtTail(int val) {
        if (getSize()==0){
            addAtHead(val);
        }else{
            ListNode node = head;
            while (node.next!=null){
                node = node.next;
            }
            node.next = new ListNode(val);
        }

        getSize(); //print();
    }
//     0   1   2   3
//     1   2   3   4
// addAtIndex(index,val)：在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度，则该节点将附加
//到链表的末尾。如果 index 大于链表长度，则不会插入节点。如果index小于0，则在头部插入节点。
    public void addAtIndex(int index, int val) {
        if (index > getSize()) {
            return;
        }
        if (index < 0) {
            index = 0;
        }
        if (index==0){
            addAtHead(val);
        }else
        if (index==getSize()){
            addAtTail(val);
        }else {
            ListNode node = head;
            ListNode addnode = new ListNode(val);
            while (index>1){
                node = node.next;
                index--;
            }
            ListNode nodeNext = node.next;
            node.next = addnode;
            addnode.next = nodeNext;
        }
        getSize();
        //print();
    }
//     0   1   2   3
//     1   2   3   4
// deleteAtIndex(index)：如果索引 index 有效，则删除链表中的第 index 个节点。
    public void deleteAtIndex(int index) {
        if (index>=0&&index<getSize()){
// 抄  删除头结点
            if (index == 0) {
                head = head.next;
                return;
            }
            ListNode node = head;
            while (index>1){
                node = node.next;
                index--;
            }

            node.next = node.next.next;
        }
        getSize(); //print();
    }
    public void print(){
        List<Integer> list = new ArrayList<Integer>();
        ListNode node = head;

        while (node!=null){
            list.add(node.val);
            node = node.next;
//            System.out.print(node.val+" ");
        }
//        System.out.println();
        System.out.println(list+"  "+getSize());
    }
}
    class ListNode {
        int val;
        ListNode next;
        ListNode() {}
        ListNode(int val) { this.val = val; }
        ListNode(int val,  ListNode next) { this.val = val; this.next = next; }
    }
/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList obj = new MyLinkedList();
 * int param_1 = obj.get(index);
 * obj.addAtHead(val);
 * obj.addAtTail(val);
 * obj.addAtIndex(index,val);
 * obj.deleteAtIndex(index);
 */
//leetcode submit region end(Prohibit modification and deletion)

}
